package com.example.score.controller;

import com.example.score.common.ErrorQuestionRedisConstants;
import com.example.score.common.Result;
import com.example.score.dto.AjaxResult;
import com.example.score.dto.ExamBaseDTO;
import com.example.score.dto.ExamDetailDTO;
import com.example.score.dto.PublishScoreDTO;
import com.example.score.entity.ClassInfo;
import com.example.score.entity.ExamBase;
import com.example.score.entity.ExamDetail;
import com.example.score.entity.StudentSubmit;
import com.example.score.mapper.ExamDetailMapper;
import com.example.score.service.ExamService;
import com.example.score.service.ReportService;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/exam")
@RequiredArgsConstructor
public class ExamController {

    private static final Logger log = LoggerFactory.getLogger(ScoreAnalysisController.class);
    private final ExamService examService;


    private final ReportService reportService;
    private final ExamDetailMapper examDetailMapper;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @PostMapping("/base")
    public AjaxResult saveExamBase(@RequestBody ExamBaseDTO examBase) throws Exception {
        //先校验，在计算
        examService.checkExamBaseInfo(examBase);
        //保存
        examService.saveExamBaseInfo(examBase);
        //同步成绩分析数据
        List<StudentSubmit> studentSubmitList = examService.syncExamDetails(examBase);
        ExamDetail examDetail = examDetailMapper.selectByExamId(examBase.getExamId());
        //同步作业提交情况
        reportService.generateSubmitStatistics(examDetail.getId());
        // 3. 生成高频错题统计
        reportService.generateFrequentWrongQuestions(examDetail.getId());
        //执行完，微信推送消息给关注的每个用户
        if (!studentSubmitList.isEmpty()) {
            log.info("模版消息开始推送······");
            List<String> studentNumbers = studentSubmitList.stream().map(StudentSubmit::getStudentNum).collect(Collectors.toList());
            examService.wxMessagePush(studentNumbers, examBase.getExamName(), examBase.getExamId(), examBase.getSubjectOnlyid(), examBase.getSubjectName());
            log.info("模版消息推送完成······");
        }
        //构建错题数据
        threadPoolTaskExecutor.execute(() -> examService.buildErrorQuestionData(examBase));
        return AjaxResult.success();
    }

    @PostMapping("/errorQuestionTest")
    public AjaxResult errorQuestionTest(@RequestBody ExamBaseDTO examBase) {
        //构建错题数据
        threadPoolTaskExecutor.execute(() -> examService.buildErrorQuestionData(examBase));
        return AjaxResult.success();
    }

    @PostMapping("/batchDispose")
    public AjaxResult batchDispose(@RequestBody List<Long> examIds) {
        //构建错题数据
        threadPoolTaskExecutor.execute(() -> {
            for (Long examId : examIds) {
                ExamBaseDTO examBaseDTO = new ExamBaseDTO();
                examBaseDTO.setExamId(examId);
                examService.buildErrorQuestionData(examBaseDTO);
            }
        });
        return AjaxResult.success();
    }


    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @GetMapping("/testRedis/{examId}")
    public AjaxResult testRedis(@PathVariable("examId") Long examId) {
        //构建错题数据
        redisTemplate.opsForValue().set(ErrorQuestionRedisConstants.ERROR_QUESTION_MQ_KEY + examId,
                ErrorQuestionRedisConstants.ERROR_QUESTION_MQ_AWAIT, 1, TimeUnit.DAYS);
        return AjaxResult.success();
    }


    /**
     * 发送模版消息
     *
     * @param studentNumbers
     * @param examName
     * @return
     * @throws Exception
     */
    @PostMapping("send/message")
    public AjaxResult sendMessage(@RequestParam(required = false) List<String> studentNumbers,
                                  @RequestParam(required = false) String examName,
                                  @RequestParam(required = false) Long examId,
                                  @RequestParam(required = false) String subjectName,
                                  @RequestParam(required = false) Long subjectId) throws Exception {
        examService.wxMessagePush(studentNumbers, examName, examId, subjectId, subjectName);
        return AjaxResult.success();
    }

    @PostMapping("/sync-details")
    public AjaxResult syncExamDetails() {
        examService.syncExamDetails(null);
        return AjaxResult.success();

    }

    @PostMapping("/publish-score")
    public AjaxResult publishScore(@RequestBody PublishScoreDTO publishScoreDTO) {
        ClassInfo classInfo = new ClassInfo();
        classInfo.setExamDetailId(publishScoreDTO.getExamDetailId());
        classInfo.setId(publishScoreDTO.getClassInfoId());
        classInfo.setClassId(publishScoreDTO.getClassId());
        classInfo.setStudentCount(publishScoreDTO.getStudentCount());
        examService.publishScore(publishScoreDTO.getSubjectId(), classInfo, null);
        return AjaxResult.success();

    }

    /**
     * 生成校本作业数据
     *
     * @param examBase
     * @return
     */
    @PostMapping("/gen/analysis")
    @Transactional
    public Result<?> publishScore(@RequestBody ExamBase examBase) {
        // 4. 生成提交作业统计
        try {
            ExamDetail examDetail = examDetailMapper.selectByExamId(examBase.getExamId());
            //同步作业提交情况
            reportService.generateSubmitStatistics(examDetail.getId());
            // 3. 生成高频错题统计
            reportService.generateFrequentWrongQuestions(examDetail.getId());
            //reportService.generateBlankRateStatistics(examDetail.getId());
        } catch (Exception e) {
            log.error("获取知识点得分率失败: {}", e.getMessage(), e);
            return Result.error("获取知识点得分率失败: " + e.getMessage());
        }
        return Result.success(null);
    }

    /**
     * 按照日期返回作业列表
     */
    @GetMapping("/list")
    public Result<?> list(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endTime,
            @RequestParam Long subjectId,
            @RequestParam Long gradeId) {
        try {
            log.info("获取作业提交情况对比 - startTime: {}, endTime: {}, subjectId: {}, gradeId: {}",
                    startTime, endTime, subjectId, gradeId);
            List<ExamBase> data = examService.selectExamListByDate(startTime, endTime, subjectId, gradeId);
            log.info("知识点得分率数据计算完成，共 {} 条记录", data.size());
            return Result.success(data);
        } catch (Exception e) {
            log.error("获取知识点得分率失败: {}", e.getMessage(), e);
            return Result.error("获取知识点得分率失败: " + e.getMessage());
        }
    }

}